package com.junzhiit.nengji.cms.service.impl;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.cms.service.CouponsService;
import com.junzhiit.nengji.cms.web.exception.ChainNotFoundException;
import com.junzhiit.nengji.cms.web.exception.CouponsAlreadyExistsException;
import com.junzhiit.nengji.cms.web.exception.CouponsNotFoundException;
import com.junzhiit.nengji.cms.web.exception.CouponsTimeException;
import com.junzhiit.nengji.cms.web.exception.RedeemcodeInsertException;
import com.junzhiit.nengji.cms.web.exception.ShopNotFoundException;
import com.junzhiit.nengji.cms.web.util.FileUtil;
import com.junzhiit.nengji.cms.web.util.ViewObjectUtil;
import com.junzhiit.nengji.cms.web.util.tools.NumberUtils;
import com.junzhiit.nengji.cms.web.vo.CouponsAddVO;
import com.junzhiit.nengji.cms.web.vo.CouponsEditVO;
import com.junzhiit.nengji.cms.web.vo.CouponsVO;
import com.junzhiit.nengji.cms.web.vo.DataTablesParamVO;
import com.junzhiit.nengji.cms.web.vo.ResultVO;
import com.junzhiit.nengji.cms.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.dao.ChainDAO;
import com.junzhiit.nengji.dao.CouponsDAO;
import com.junzhiit.nengji.dao.RedeemCodeDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.UserCouponsDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Chain;
import com.junzhiit.nengji.model.Coupons;
import com.junzhiit.nengji.model.RedeemCode;
import com.junzhiit.nengji.model.Shop;
import com.junzhiit.nengji.model.UserCoupons;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.SystemUserType;

@Service
public class CouponsServiceImpl extends BaseServiceImpl implements CouponsService {

	@Autowired
	private CouponsDAO couponsDAO;

	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;

	@Autowired
	private ShopDAO shopDAO;

	@Autowired
	private ChainDAO chainDAO;

	@Autowired
	private RedeemCodeDAO redeemCodeDAO;

	@Value("${upload.mall.coupons.qrcode}")
	private String qrcodePath;

	@Value("${wap.event.coupons.page}")
	private String eventCoupons;

	@Autowired
	private UserCouponsDAO userCouponsDAO;

	@Override
	public Map<String, Object> findAll(DataTablesParamVO dtp, CouponsVO couponsVO) {
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsVO.getSessionId()), SystemUserSessionVO.class);

		Coupons coupons = new Coupons();
		BeanUtils.copyProperties(couponsVO, coupons);

		if (systemUserSessionVO.getLoginType().intValue() == SystemUserType.SHOP.toIntStatus()) {
			if (Is.NO.toIntValue() == couponsVO.getIsChain().intValue()) {
				// 店铺
				Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
				if (shop == null) {
					throw new ShopNotFoundException("店铺不存在");
				}
				coupons.setShopId(shop.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			} else if (Is.YES.toIntValue() == couponsVO.getIsChain().intValue()) {
				// 连锁品牌
				Chain chain = chainDAO.query(systemUserSessionVO.getSystemId());
				if (chain == null) {
					throw new ChainNotFoundException("连锁品牌不存在");
				}
				coupons.setChainId(chain.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}
		} else if (systemUserSessionVO.getLoginType().intValue() == SystemUserType.INTERNAL.toIntStatus()) {
			coupons.setPlatform(SystemUserType.INTERNAL.toIntStatus());
		}

		List<Coupons> list = couponsDAO.findAll(coupons, dtp.getStart(), dtp.getLength());
		int totalCount = couponsDAO.getTotalCount(coupons);

		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}

	@Override
	public ResultVO findById(String id) {
		ResultVO result = new ResultVO();
		Coupons coupons = couponsDAO.query(id);
		if (coupons == null) {
			throw new CouponsNotFoundException("优惠卷未找到");
		}
		result.setData(coupons);
		return result;
	}

	@Override
	public ResultVO add(CouponsAddVO couponsAddVO) {
		ResultVO result = new ResultVO();

		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsAddVO.getSessionId()), SystemUserSessionVO.class);
		
		if(couponsAddVO.getValidTimeState()==Is.NO.toIntValue() ){
			if(couponsAddVO.getValidEndTime().getTime()>=couponsAddVO.getUnderTime().getTime()){
				throw new CouponsTimeException("优惠卷有效结束时间必须小于下架时间");
			}
			
			if(couponsAddVO.getValidEndTime().getTime()<=couponsAddVO.getValidStartTime().getTime()){
				throw new CouponsTimeException("优惠卷有效结束时间必须大于有效开始时间");
			}
		}
		
		Coupons coupons = new Coupons();
		if(couponsAddVO.getValidTimeState()==Is.NO.toIntValue()){
			coupons.setValidStartTime(DateUtil.getDateStart(couponsAddVO.getValidStartTime()));
			coupons.setValidEndTime(DateUtil.getDateEnd(couponsAddVO.getValidEndTime()));
		}
		
		BeanUtils.copyProperties(couponsAddVO, coupons);

		if (systemUserSessionVO.getLoginType().intValue() == SystemUserType.SHOP.toIntStatus()) {

			if (Is.NO.toIntValue() == couponsAddVO.getIsChain().intValue()) {
				// 店铺
				Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
				if (shop == null) {
					throw new ShopNotFoundException("店铺不存在");
				}
				coupons.setShopId(shop.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			} else if (Is.YES.toIntValue() == couponsAddVO.getIsChain().intValue()) {
				// 连锁品牌
				Chain chain = chainDAO.query(systemUserSessionVO.getSystemId());
				if (chain == null) {
					throw new ChainNotFoundException("连锁品牌不存在");
				}
				coupons.setChainId(chain.getId());
				coupons.setPlatform(SystemUserType.SHOP.toIntStatus());
			}

		} else if (systemUserSessionVO.getLoginType().intValue() == SystemUserType.INTERNAL.toIntStatus()) {
			coupons.setPlatform(SystemUserType.INTERNAL.toIntStatus());
		}
		coupons.setStatus(Is.YES.toIntValue());
		coupons.setPlatform(systemUserSessionVO.getLoginType());

		Coupons data = couponsDAO.insert(coupons);
		if (couponsAddVO.getIsLimitCount() == Is.YES.toIntValue()) {
			Integer limitCount = couponsAddVO.getLimitCount();
			Integer length = 10;
			List<String> codeList = NumberUtils.getStringRandom(limitCount, length);
			List<RedeemCode> rcList = new ArrayList<RedeemCode>();
			for (String code : codeList) {
				RedeemCode rc = new RedeemCode();
				rc.setCode(code);
				rc.setCouponsId(data.getId());
				rc.setStatus(Is.NO.toIntValue());
				rcList.add(rc);
			}
			int i = redeemCodeDAO.batchInsert(rcList);
			if (i == 1) {
				throw new RedeemcodeInsertException("兑换码添加异常");
			}
		}
		result.setData(data);

		return result;
	}

	@Override
	public ResultVO edit(CouponsEditVO couponsEditVO) {
		ResultVO result = new ResultVO();
		Coupons coupons = new Coupons();
		BeanUtils.copyProperties(couponsEditVO, coupons);

		boolean data = couponsDAO.update(coupons);
		result.setData(data);
		return result;
	}

	@Override
	public ResultVO updateStatus(String id, Integer status) {
		ResultVO result = new ResultVO();

		Coupons coupons = new Coupons();
		coupons.setId(id);
		status = (status == 1) ? 1 : 0;
		coupons.setStatus(status);

		boolean data = couponsDAO.update(coupons);
		result.setData(data);

		return result;
	}

	@Override
	public ResultVO getCouponsList(CouponsVO couponsVO) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(couponsVO.getSessionId()), SystemUserSessionVO.class);
		// 平台单店及连锁品牌单店优惠券查询
		if (systemUserSessionVO.getIsChain() == Is.NO.toIntValue()) {
			Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
			if (shop == null) {
				throw new ShopNotFoundException("店铺不存在");
			}
			result.setData(couponsDAO.getCouponsList(shop.getId(), Is.NO.toIntValue()));
		}
		// 连锁品牌平台优惠券查询
		if (systemUserSessionVO.getIsChain() == Is.YES.toIntValue()) {
			Chain chain = chainDAO.query(systemUserSessionVO.getSystemId());
			if (chain == null) {
				throw new ShopNotFoundException("品牌不存在");
			}
			result.setData(couponsDAO.getCouponsList(chain.getId(), Is.YES.toIntValue()));
		}

		return result;
	}

	@Override
	public void soldOutCoupons() {
		List<Coupons> coupons = couponsDAO.getCoupons(Is.YES.toIntValue());
		Date now = new Date();
		for (Coupons coupon : coupons) {
			if (coupon.getUnderTime()!=null && coupon.getUnderTime().getTime() <= now.getTime()) {
				coupon.setStatus(0);
				couponsDAO.update(coupon);
			}
		}
	}

	public ResultVO createQRCode(String id) {
		ResultVO result = new ResultVO();

		String qrcodeName = id + "." + FileUtil.QR_CODE_FORMAT;
		String fullpath = qrcodePath + qrcodeName;

		if (StringUtils.isNotBlank(id)) {
			File file = new File(fullpath);
			if (file.exists())
				FileUtil.removeFile(fullpath);
		}
		String content = eventCoupons + "?id=" + id;

		FileUtil.createQRCode(content, fullpath);
		Map<String, String> data = new HashMap<String, String>();
		data.put("qrcodeName", qrcodeName);
		data.put("qrcodePath", content);
		result.setData(data);
		return result;
	}

	public void downloadQRCode(HttpServletRequest request, HttpServletResponse response, String qrcodeName,
			String couponsName) {
		try {
			String qrcode = qrcodePath + qrcodeName;
			String fileName = qrcodeName;

			// 中文名乱码浏览器兼容
			String agent = request.getHeader("USER-AGENT");
			if (null != agent && -1 != agent.indexOf("MSIE") || null != agent && -1 != agent.indexOf("Trident")) {// IE
				fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
			}

			File file = new File(qrcode);
			if (file.exists())
				FileUtil.download(request, response, qrcode, fileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public ResultVO insert(String userId, String couponsId) {
		ResultVO result = new ResultVO();
		Coupons coupons = couponsDAO.query(couponsId);
		UserCoupons userCoupons = userCouponsDAO.getUserCouponsByCouponsId(userId, couponsId);
		if (userCoupons != null) {
			throw new CouponsAlreadyExistsException("该优惠劵已经领取过");
		}
		userCoupons = new UserCoupons();
		BeanUtils.copyProperties(coupons, userCoupons);
		if (coupons.getValidTimeState() == 0) {
			userCoupons.setStartTime(coupons.getValidStartTime());
			userCoupons.setEndTime(coupons.getValidEndTime());
		} else {
			Date now = new Date();
			Date date = DateUtil.addDays(now, coupons.getValidDays());
			userCoupons.setStartTime(now);
			userCoupons.setEndTime(date);
		}
		userCoupons.setStatus(Is.NO.toIntValue());
		userCoupons.setUserId(userId);
		userCoupons.setShopId(coupons.getShopId());
		userCoupons.setCouponsName(coupons.getName());
		userCoupons.setCouponsId(couponsId);
		userCoupons.setCouponsType(coupons.getType());
		if (coupons.getType() == 0) {
			// 等于1为随机劵
			if (coupons.getIsOpenRandom() == 1) {
				// 在条件为0.6,3的10万次测试中取Max、Min的比例为0.053%，在1-100区间内大于60的占30%
				Double offer = this.randomWeights(coupons.getStartPrice(), coupons.getEndPrice(), 0.6, 2);
				userCoupons.setPrice(offer);
			} else {
				userCoupons.setPrice(coupons.getPrice());
			}
		}
		result.setData(userCouponsDAO.insert(userCoupons));
		return result;
	}

	/**
	 * maxProportion：代表权重衡量的区间段的大小,取值为(0.1~0.9),值越大代表权重区间值越小即越接近于Max
	 * weights：权重,取值为(1~9),值越大代表在权重区间取值的比重越大
	 */
	private Double randomWeights(Double min, Double max, Double maxProportion, int weights) {
		weights = weights >= 10 && weights < 0 ? 1 : weights;
		maxProportion = maxProportion >= 1 && maxProportion < 0 ? 0.1 : maxProportion;
		Double median = (maxProportion * (max - min)) + min;
		Double result = new Double(0);
		List<Double> list = new ArrayList<Double>();
		for (int i = 1; i <= 10; i++) {
			if (i <= weights) {
				list.add((Math.random() * (max - median)) + median);
			} else {
				list.add((Math.random() * (median - min)) + min);
			}
		}
		result = list.get((int) (1 + Math.random() * (10 - 1)));
		return Double.parseDouble(new DecimalFormat("#.##").format(result));
	}

	@Override
	public ResultVO queryAll(String sessionId) {
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO.getHash(DIYKey.getSessionHashKey(sessionId),SystemUserSessionVO.class);
		String systemId = systemUserSessionVO.getSystemId();
		Shop shop = shopDAO.query(systemUserSessionVO.getSystemId());
		if (shop == null) {
			throw new ShopNotFoundException("店铺不存在");
		}
		Coupons coupons=new Coupons();
		coupons.setShopId(systemId);
		List<Coupons> couponsList=couponsDAO.queryAll(coupons);
		result.setData(couponsList);
		return result;
	}
}
